namespace C1.Win.C1FlexGrid
{
    using C1.Win.C1FlexGrid.Util.Styles;
    using System;
    using System.Drawing;
    using System.Windows.Forms;

    internal class GridMouseHandler
    {
        protected int _dragMax;
        protected int _dragMin;
        protected int _dragTarget;
        protected bool _frozenCol;
        protected bool _frozenRow;
        protected HitTestInfo _htDown;
        protected HitTestInfo _htDrag;
        protected bool _listSelect;
        protected RowCollection _listSelection;
        protected Marquee _marquee;
        protected Rectangle _scroll;
        protected Timer _scrollTimer;
        protected MouseStateEnum _state;
        protected C1FlexGridBase _view;
        internal const int MOUSE_THRESHOLD_DRAG = 10;
        internal const int MOUSE_THRESHOLD_SCRL = 3;
        internal const int MOUSE_THRESHOLD_SIZE = 3;
        internal const int MOUSE_TIMER_DELAY = 50;

        internal GridMouseHandler(C1FlexGridBase view)
        {
            this._view = view;
            this._scrollTimer = new Timer();
            this._scrollTimer.Interval = 50;
            this._scrollTimer.Enabled = false;
            this._scrollTimer.Tick += new EventHandler(this.TimerTick);
            this._marquee = new Marquee(view);
        }

        protected bool AllowDragCol(int col)
        {
            AllowDraggingEnum allowDragging = this._view.AllowDragging;
            if ((allowDragging != AllowDraggingEnum.Columns) && (allowDragging != AllowDraggingEnum.Both))
            {
                return false;
            }
            return this._view.Cols[col].AllowDragging;
        }

        protected bool AllowDragRow(int row)
        {
            AllowDraggingEnum allowDragging = this._view.AllowDragging;
            if ((allowDragging != AllowDraggingEnum.Rows) && (allowDragging != AllowDraggingEnum.Both))
            {
                return false;
            }
            return this._view.Rows[row].AllowDragging;
        }

        protected bool AllowSortCol(int col)
        {
            if (this._view.AllowSorting == AllowSortingEnum.None)
            {
                return false;
            }
            if (col < this._view.Cols.Fixed)
            {
                return false;
            }
            return this._view.Cols[col].AllowSorting;
        }

        internal void CancelDragResize()
        {
            switch (this._state)
            {
                case MouseStateEnum.ResizingRow:
                case MouseStateEnum.ResizingCol:
                case MouseStateEnum.FreezingRow:
                case MouseStateEnum.FreezingCol:
                case MouseStateEnum.PreDraggingRow:
                case MouseStateEnum.PreDraggingCol:
                case MouseStateEnum.DraggingRow:
                case MouseStateEnum.DraggingCol:
                    this.ResetMouse();
                    break;

                case MouseStateEnum.PreFreezingRow:
                case MouseStateEnum.PreFreezingCol:
                    break;

                default:
                    return;
            }
        }

        protected int GetFreezeCol(int x, int y)
        {
            AllowFreezingEnum allowFreezing = this._view.AllowFreezing;
            if ((allowFreezing != AllowFreezingEnum.Columns) && (allowFreezing != AllowFreezingEnum.Both))
            {
                return -1;
            }
            RowColCollection cols = this._view.Cols;
            Point cellAt = this._view.GetCellAt(x, y);
            if (cellAt.X != ((cols.Fixed + cols.Frozen) - 1))
            {
                return -1;
            }
            if (cellAt.Y < cols.Fixed)
            {
                return -1;
            }
            int col = -1;
            if ((this._view.GetCellRectDisplay(cellAt.Y, cellAt.X).Right - x) < 3)
            {
                col = cellAt.X;
            }
            if (this._view.ExtendCol(col))
            {
                return -1;
            }
            return col;
        }

        protected int GetFreezeRow(int x, int y)
        {
            AllowFreezingEnum allowFreezing = this._view.AllowFreezing;
            if ((allowFreezing != AllowFreezingEnum.Rows) && (allowFreezing != AllowFreezingEnum.Both))
            {
                return -1;
            }
            RowColCollection rows = this._view.Rows;
            Point cellAt = this._view.GetCellAt(x, y);
            if (cellAt.Y != ((rows.Fixed + rows.Frozen) - 1))
            {
                return -1;
            }
            if (cellAt.X < rows.Fixed)
            {
                return -1;
            }
            int num = -1;
            if ((this._view.GetCellRectDisplay(cellAt.Y, cellAt.X).Bottom - y) < 3)
            {
                num = cellAt.Y;
            }
            return num;
        }

        internal int GetOutlineButton(int x, int y, int row, int col)
        {
            GridTree tree = this._view._grid._tree;
            if (tree.TreeWidth(col) != 0)
            {
                if ((!tree.IsFlagSet(TreeStyleFlags.ButtonBar) || (row > 0)) || (this._view.Rows.Fixed == 0))
                {
                    return -1;
                }
                Rectangle cellRectDisplay = this._view.GetCellRectDisplay(row, col);
                int num = this._view.Rows._maxNodeLevel;
                for (int i = 0; i <= (num + 1); i++)
                {
                    if (tree.GetButtonRect(cellRectDisplay, i).Contains(x, y))
                    {
                        return i;
                    }
                }
            }
            return -1;
        }

        protected int GetResizeCol(int x, int y)
        {
            AllowResizingEnum allowResizing = this._view.AllowResizing;
            if (((allowResizing != AllowResizingEnum.Columns) && (allowResizing != AllowResizingEnum.Both)) && (allowResizing != AllowResizingEnum.BothUniform))
            {
                return -1;
            }
            Point cellAt = this._view.GetCellAt(x, y);
            if (((cellAt.X < 0) || (cellAt.Y < 0)) || (cellAt.Y >= this._view.Rows.Fixed))
            {
                return -1;
            }
            int col = -1;
            Rectangle cellRectDisplay = this._view.GetCellRectDisplay(cellAt.Y, cellAt.X);
            if ((cellRectDisplay.Right - x) < 3)
            {
                col = cellAt.X;
            }
            if ((x - cellRectDisplay.X) < 3)
            {
                col = cellAt.X - 1;
            }
            while ((col > 0) && (this._view.Cols[col].SizeDisplay == 0))
            {
                col--;
            }
            if ((col < 0) || !this._view.Cols[col].AllowResizing)
            {
                return -1;
            }
            if (this._view.ExtendCol(col))
            {
                return -1;
            }
            return col;
        }

        protected int GetResizeRow(int x, int y)
        {
            switch (this._view.AllowResizing)
            {
                case AllowResizingEnum.Rows:
                case AllowResizingEnum.Both:
                case AllowResizingEnum.RowsUniform:
                case AllowResizingEnum.BothUniform:
                {
                    Point cellAt = this._view.GetCellAt(x, y);
                    if (((cellAt.X < 0) || (cellAt.Y < 0)) || (cellAt.X >= this._view.Cols.Fixed))
                    {
                        return -1;
                    }
                    int num = -1;
                    Rectangle cellRectDisplay = this._view.GetCellRectDisplay(cellAt.Y, cellAt.X);
                    if ((cellRectDisplay.Bottom - y) < 5)
                    {
                        num = cellAt.Y;
                    }
                    if ((y - cellRectDisplay.Y) < 3)
                    {
                        num = cellAt.Y - 1;
                    }
                    while ((num > 0) && (this._view.Rows[num].SizeDisplay == 0))
                    {
                        num--;
                    }
                    if ((num > -1) && this._view.Rows[num].AllowResizing)
                    {
                        return num;
                    }
                    break;
                }
            }
            return -1;
        }

        protected int GetTargetCol(bool dragging)
        {
            int col = dragging ? this._view.LeftCol : this._view.Cols.Fixed;
            while (col < this._view.Cols.Count)
            {
                Rectangle rectangle = this._view.GetCellRectDisplay(0, col, true);
                if (this._htDrag.X < (rectangle.Left + (rectangle.Width / 2)))
                {
                    break;
                }
                col++;
            }
            if (col > this._dragMax)
            {
                col = this._dragMax + 1;
            }
            if (col < this._dragMin)
            {
                col = this._dragMin;
            }
            return col;
        }

        protected int GetTargetRow(bool dragging)
        {
            int row = dragging ? this._view.TopRow : this._view.Rows.Fixed;
            while (row < this._view.Rows.Count)
            {
                Rectangle rectangle = this._view.GetCellRectDisplay(row, 0, true);
                if (this._htDrag.Y < (rectangle.Top + (rectangle.Height / 2)))
                {
                    break;
                }
                row++;
            }
            if (row > this._dragMax)
            {
                row = this._dragMax + 1;
            }
            if (row < this._dragMin)
            {
                row = this._dragMin;
            }
            return row;
        }

        internal bool GetTreeButton(int x, int y, int row, int col)
        {
            GridTree tree = this._view._grid._tree;
            if (tree.TreeWidth(col) == 0)
            {
                return false;
            }
            if (!tree.IsFlagSet(TreeStyleFlags.Symbols))
            {
                return false;
            }
            if (row < 0)
            {
                return false;
            }
            Row row2 = this._view.Rows[row];
            if (!row2.IsNode)
            {
                return false;
            }
            Node node = row2.Node;
            Rectangle cellRectDisplay = this._view.GetCellRectDisplay(row, col);
            return tree.GetSymbolRect(cellRectDisplay, node.Level).Contains(x, y);
        }

        internal bool HandleDoubleClick()
        {
            if (this._htDown.Type == HitTestTypeEnum.ColumnResize)
            {
                this.ResetMouse();
                RowColEventArgs e = new RowColEventArgs(-1, this._htDown.Column);
                this._view.OnBeforeAutosizeRowCol(e);
                if (!e.Cancel)
                {
                    this._view.AutoSizeCol(this._htDown.Column);
                    this._view.OnAfterResizeRowCol(e);
                }
                return true;
            }
            if (this._htDown.Type == HitTestTypeEnum.RowResize)
            {
                this.ResetMouse();
                RowColEventArgs args2 = new RowColEventArgs(this._htDown.Row, -1);
                this._view.OnBeforeAutosizeRowCol(args2);
                if (!args2.Cancel)
                {
                    this._view.AutoSizeRow(this._htDown.Row);
                    switch (this._view.AllowResizing)
                    {
                        case AllowResizingEnum.RowsUniform:
                        case AllowResizingEnum.BothUniform:
                            this._view.Rows.DefaultSize = this._view.Rows[this._htDown.Row].HeightDisplay;
                            this.ResizeRow(this._htDown.Row, -1);
                            break;
                    }
                    this._view.OnAfterResizeRowCol(args2);
                }
                return true;
            }
            if (this.HandleDownEditor(true))
            {
                return true;
            }
            this.ResetMouse();
            return false;
        }

        internal bool HandleDown(MouseEventArgs e)
        {
            this._htDown = this._htDrag = this.HitTest(e.X, e.Y);
            switch (this._htDown.Type)
            {
                case HitTestTypeEnum.ColumnHeader:
                case HitTestTypeEnum.RowHeader:
                    if (!this.HandleDownHeaders())
                    {
                        break;
                    }
                    return true;

                case HitTestTypeEnum.ColumnResize:
                    this._state = MouseStateEnum.PreResizingCol;
                    if (!this.HandleDownResizing())
                    {
                        break;
                    }
                    return true;

                case HitTestTypeEnum.ColumnFreeze:
                    this._state = MouseStateEnum.PreFreezingCol;
                    if (!this.HandleDownFreezing())
                    {
                        break;
                    }
                    return true;

                case HitTestTypeEnum.RowResize:
                    this._state = MouseStateEnum.PreResizingRow;
                    if (!this.HandleDownResizing())
                    {
                        break;
                    }
                    return true;

                case HitTestTypeEnum.RowFreeze:
                    this._state = MouseStateEnum.PreFreezingRow;
                    if (!this.HandleDownFreezing())
                    {
                        break;
                    }
                    return true;

                case HitTestTypeEnum.Checkbox:
                case HitTestTypeEnum.EditButton:
                    if (!this.HandleDownEditor(false))
                    {
                        break;
                    }
                    return true;

                case HitTestTypeEnum.OutlineBar:
                case HitTestTypeEnum.OutlineTree:
                    if (!this.HandleDownTree())
                    {
                        break;
                    }
                    return true;
            }
            if (this.HandleDownSelection())
            {
                this._scrollTimer.Enabled = true;
                return true;
            }
            return false;
        }

        internal bool HandleDownEditor(bool dblClick)
        {
            int row = this._htDown.Row;
            int column = this._htDown.Column;
            if (this._view._grid.IsBadRowCol(row, column))
            {
                return false;
            }
            if (this._view.EditHandler.GetEditorType(row, column) != EditorTypeEnum.Checkbox)
            {
                if (this._view._grid.IsCellFixed(row, column))
                {
                    return false;
                }
                if (!dblClick && !this._view.CellHasButton(row, column))
                {
                    return false;
                }
            }
            Point ptMouse = new Point(this._htDown.X, this._htDown.Y);
            if (!this._view.StartEditing(row, column, ptMouse, dblClick))
            {
                return false;
            }
            this.ResetMouse();
            return true;
        }

        internal bool HandleDownFreezing()
        {
            if (this._htDown.Type == HitTestTypeEnum.ColumnFreeze)
            {
                RowColEventArgs e = new RowColEventArgs(-1, this._view.Cols.Frozen);
                this._view.OnBeforeFreezeRowCol(e);
                if (!e.Cancel)
                {
                    this._state = MouseStateEnum.FreezingCol;
                    this.UpdateFreezeCol(true);
                    return true;
                }
            }
            if (this._htDown.Type == HitTestTypeEnum.RowFreeze)
            {
                RowColEventArgs args2 = new RowColEventArgs(this._view.Rows.Frozen, -1);
                this._view.OnBeforeFreezeRowCol(args2);
                if (!args2.Cancel)
                {
                    this._state = MouseStateEnum.FreezingRow;
                    this.UpdateFreezeRow(true);
                    return true;
                }
            }
            return false;
        }

        internal bool HandleDownHeaders()
        {
            if ((this._htDown.Column < 0) || (this._htDown.Row < 0))
            {
                return false;
            }
            if (this._htDown.Type == HitTestTypeEnum.ColumnHeader)
            {
                if (!this.AllowDragCol(this._htDown.Column) && !this.AllowSortCol(this._htDown.Column))
                {
                    return false;
                }
                this._state = MouseStateEnum.PreDraggingCol;
                return true;
            }
            if (this._htDown.Type != HitTestTypeEnum.RowHeader)
            {
                return false;
            }
            if (!this.AllowDragRow(this._htDown.Row))
            {
                return false;
            }
            this._state = MouseStateEnum.PreDraggingRow;
            return true;
        }

        internal bool HandleDownResizing()
        {
            if (this._htDown.Type == HitTestTypeEnum.ColumnResize)
            {
                RowColEventArgs e = new RowColEventArgs(-1, this._htDown.Column);
                this._view.OnBeforeResizeRowCol(e);
                if (!e.Cancel)
                {
                    this._state = MouseStateEnum.ResizingCol;
                    this.UpdateResizeCol(true);
                    return true;
                }
            }
            if (this._htDown.Type == HitTestTypeEnum.RowResize)
            {
                RowColEventArgs args2 = new RowColEventArgs(this._htDown.Row, -1);
                this._view.OnBeforeResizeRowCol(args2);
                if (!args2.Cancel)
                {
                    this._state = MouseStateEnum.ResizingRow;
                    this.UpdateResizeRow(true);
                    return true;
                }
            }
            return false;
        }

        internal bool HandleDownSelection()
        {
            CellRange rg = new CellRange(this._view._grid, this._htDown.Row, this._htDown.Column);
            if ((rg.r1 < 0) || (rg.c1 < 0))
            {
                return false;
            }
            bool flag = this._view._shift;
            bool flag2 = this._view._control;
            bool flag3 = this._view.Rows.IsFixed(rg.r1);
            bool flag4 = this._view.Cols.IsFixed(rg.c1);
            if (flag3)
            {
                rg.r1 = this._view.Rows.Fixed;
                rg.r2 = this._view.Rows.Count - 1;
                if (rg.r1 > rg.r2)
                {
                    rg.r1 = rg.r2;
                }
            }
            if (flag4)
            {
                rg.c1 = this._view.Cols.Fixed;
                rg.c2 = this._view.Cols.Count - 1;
                if (rg.c1 > rg.c2)
                {
                    rg.c1 = rg.c2;
                }
            }
            this._frozenCol = !flag4 && this._view.Cols.IsFrozen(this._htDown.Column);
            this._frozenRow = !flag3 && this._view.Rows.IsFrozen(this._htDown.Row);
            switch (this._view.SelectionMode)
            {
                case SelectionModeEnum.Default:
                    if (!flag3 || !flag4)
                    {
                        break;
                    }
                    if (rg.IsValid)
                    {
                        this._view.Select(rg, false);
                    }
                    return true;

                case SelectionModeEnum.Cell:
                case SelectionModeEnum.CellRange:
                    if (flag3)
                    {
                        rg.r1 = rg.r2 = this._view.Row;
                    }
                    if (flag4)
                    {
                        rg.c1 = rg.c2 = this._view.Col;
                    }
                    break;

                case SelectionModeEnum.Row:
                case SelectionModeEnum.RowRange:
                case SelectionModeEnum.ListBox:
                    if (!flag3)
                    {
                        if (flag4)
                        {
                            rg.c1 = rg.c2 = this._view.Col;
                        }
                        break;
                    }
                    return false;

                case SelectionModeEnum.Column:
                case SelectionModeEnum.ColumnRange:
                    if (!flag4)
                    {
                        if (flag3)
                        {
                            rg.r1 = rg.r2 = this._view.Row;
                        }
                        break;
                    }
                    return false;
            }
            if (flag2 && (this._view.SelectionMode == SelectionModeEnum.ListBox))
            {
                this._state = MouseStateEnum.SelectingList;
                this._listSelection = this._view.Rows.GetSelection();
                this._listSelect = !this._view.Rows[this._htDown.Row].Selected;
                this._view.SelectList(this._htDown.Row, this._view.Col, this._listSelect, null);
                return true;
            }
            this._state = MouseStateEnum.Selecting;
            if (flag3)
            {
                this._state = MouseStateEnum.SelectingCols;
            }
            if (flag4)
            {
                this._state = MouseStateEnum.SelectingRows;
            }
            if (this._view.Rows.Count == this._view.Rows.Fixed)
            {
                rg.r1 = rg.r2 = -1;
            }
            if (this._view.Cols.Count == this._view.Cols.Fixed)
            {
                rg.c1 = rg.c2 = -1;
            }
            if (flag && this._view.SelHandler.CanExtend())
            {
                this._view.ExtendSelection(rg.r1, rg.c1, false);
            }
            else if (rg.IsValid)
            {
                this._view.Select(rg, false);
            }
            return true;
        }

        internal bool HandleDownTree()
        {
            int level = this.GetOutlineButton(this._htDown.X, this._htDown.Y, this._htDown.Row, this._htDown.Column);
            if (level > -1)
            {
                this._view._grid._tree.Show(level);
                return true;
            }
            if (this.GetTreeButton(this._htDown.X, this._htDown.Y, this._htDown.Row, this._htDown.Column))
            {
                Node node = this._view.Rows[this._htDown.Row].Node;
                node.Collapsed = !node.Collapsed;
                return true;
            }
            return false;
        }

        internal bool HandleDrag(MouseEventArgs e)
        {
            this._htDrag = this.HitTest(e.X, e.Y);
            switch (this._state)
            {
                case MouseStateEnum.ResizingRow:
                    this.UpdateResizeRow(false);
                    return true;

                case MouseStateEnum.ResizingCol:
                    this.UpdateResizeCol(false);
                    return true;

                case MouseStateEnum.FreezingRow:
                    this.UpdateFreezeRow(false);
                    return true;

                case MouseStateEnum.FreezingCol:
                    this.UpdateFreezeCol(false);
                    return true;

                case MouseStateEnum.PreDraggingRow:
                    if (!this.AllowDragRow(this._htDown.Row) || (Math.Abs((int) (e.Y - this._htDown.Y)) <= 10))
                    {
                        break;
                    }
                    this._scroll = this._view.ScrollRectangle;
                    this.UpdateDragRow(true);
                    return true;

                case MouseStateEnum.PreDraggingCol:
                    if (!this.AllowDragCol(this._htDown.Column) || (Math.Abs((int) (e.X - this._htDown.X)) <= 10))
                    {
                        break;
                    }
                    this._scroll = this._view.ScrollRectangle;
                    this.UpdateDragCol(true);
                    return true;

                case MouseStateEnum.DraggingRow:
                {
                    int rows = 0;
                    if ((this._scroll.Bottom - e.Y) < 3)
                    {
                        rows = 1;
                    }
                    if ((e.Y - this._scroll.Top) < 3)
                    {
                        rows = -1;
                    }
                    if ((rows != 0) && this.ScrollWhileDragging(0, rows))
                    {
                        return this.HandleDrag(e);
                    }
                    this.UpdateDragRow(false);
                    return true;
                }
                case MouseStateEnum.DraggingCol:
                {
                    int cols = 0;
                    if ((this._scroll.Right - e.X) < 3)
                    {
                        cols = 1;
                    }
                    if ((e.X - this._scroll.Left) < 3)
                    {
                        cols = -1;
                    }
                    if ((cols != 0) && this.ScrollWhileDragging(cols, 0))
                    {
                        return this.HandleDrag(e);
                    }
                    this.UpdateDragCol(false);
                    return true;
                }
            }
            return this.HandleDragSelection();
        }

        internal bool HandleDragSelection()
        {
            Point point = this._view.GetCellAt(this._htDrag.X, this._htDrag.Y, true);
            Point point2 = this._view.GetCellAt(this._htDrag.X, this._htDrag.Y, false);
            Point pt = new Point(0, 0);
            pt.X = this._frozenCol ? point.X : point2.X;
            pt.Y = this._frozenRow ? point.Y : point2.Y;
            if (this._frozenCol && !this._view.Cols.IsFrozen(pt.X))
            {
                this._frozenCol = false;
            }
            if (this._frozenRow && !this._view.Rows.IsFrozen(pt.Y))
            {
                this._frozenRow = false;
            }
            if (pt.X < -1)
            {
                pt.X = this._view.Cols.Count - 1;
            }
            if (pt.Y < -1)
            {
                pt.Y = this._view.Rows.Count - 1;
            }
            if (pt.Y < this._view.Rows.Fixed)
            {
                pt.Y = this._view.Rows.Fixed;
            }
            if (pt.X < this._view.Cols.Fixed)
            {
                pt.X = this._view.Cols.Fixed;
            }
            bool flag = this._view.SelHandler.CanExtend();
            switch (this._state)
            {
                case MouseStateEnum.Selecting:
                    if (!flag)
                    {
                        this._view.Select(pt, true);
                        break;
                    }
                    this._view.ExtendSelection(pt, true);
                    break;

                case MouseStateEnum.SelectingRows:
                    if (!flag)
                    {
                        this._view.Select(pt.Y, this._view.Col, true);
                    }
                    else
                    {
                        this._view.ExtendSelection(pt.Y, this._view.ColSel, false);
                    }
                    this._view.ShowCell(this._view.RowSel, -1);
                    return true;

                case MouseStateEnum.SelectingCols:
                    if (!flag)
                    {
                        this._view.Select(this._view.Row, pt.X, true);
                    }
                    else
                    {
                        this._view.ExtendSelection(this._view.RowSel, pt.X, false);
                    }
                    this._view.ShowCell(-1, this._view.ColSel);
                    return true;

                case MouseStateEnum.SelectingList:
                    this._view.SelectList(pt.Y, pt.X, this._listSelect, this._listSelection);
                    return true;

                default:
                    return false;
            }
            return true;
        }

        internal bool HandleMove(MouseEventArgs e)
        {
            if (this._view.Capture)
            {
                return this.HandleDrag(e);
            }
            if (this._state != MouseStateEnum.None)
            {
                this.ResetMouse();
            }
            switch (this.HitTest(e.X, e.Y).Type)
            {
                case HitTestTypeEnum.ColumnResize:
                    this._state = MouseStateEnum.PreResizingCol;
                    return true;

                case HitTestTypeEnum.ColumnFreeze:
                    this._state = MouseStateEnum.PreFreezingCol;
                    return true;

                case HitTestTypeEnum.RowResize:
                    this._state = MouseStateEnum.PreResizingRow;
                    return true;

                case HitTestTypeEnum.RowFreeze:
                    this._state = MouseStateEnum.PreFreezingRow;
                    return true;
            }
            return false;
        }

        internal bool HandleUp()
        {
            if (this._state == MouseStateEnum.ResizingCol)
            {
                RowColEventArgs args = new RowColEventArgs(-1, this._htDown.Column);
                int num = this._view.Cols[this._htDown.Column].WidthDisplay + (this._htDrag.X - this._htDown.X);
                if (num < 1)
                {
                    num = 1;
                }
                if (this._view.AllowResizing == AllowResizingEnum.BothUniform)
                {
                    this._view.Cols.DefaultSize = num;
                    this.ResizeCol(this._htDown.Column, -1);
                }
                else
                {
                    this.ResizeCol(this._htDown.Column, num);
                }
                this.ResetMouse();
                this._view.OnAfterResizeRowCol(args);
                return true;
            }
            if (this._state != MouseStateEnum.ResizingRow)
            {
                if (this._state == MouseStateEnum.FreezingCol)
                {
                    this._view.Cols.Frozen = this._dragTarget - this._view.Cols.Fixed;
                    RowColEventArgs args3 = new RowColEventArgs(-1, this._view.Cols.Frozen);
                    this.ResetMouse();
                    this._view.OnAfterFreezeRowCol(args3);
                    return true;
                }
                if (this._state == MouseStateEnum.FreezingRow)
                {
                    this._view.Rows.Frozen = this._dragTarget - this._view.Rows.Fixed;
                    RowColEventArgs args4 = new RowColEventArgs(this._view.Rows.Frozen, -1);
                    this.ResetMouse();
                    this._view.OnAfterFreezeRowCol(args4);
                    return true;
                }
                if (this._state == MouseStateEnum.DraggingCol)
                {
                    int column = this._htDown.Column;
                    int position = this._dragTarget;
                    if ((position != column) && (position != (column + 1)))
                    {
                        if (position > column)
                        {
                            position--;
                        }
                        DragRowColEventArgs args5 = new DragRowColEventArgs(-1, column, position);
                        this._view.OnBeforeDragRowCol(args5);
                        if (!args5.Cancel)
                        {
                            this._view.Cols.Move(args5.Col, args5.Position);
                            this._view.OnAfterDragRowCol(args5);
                        }
                    }
                    this._view.Invalidate();
                    this.ResetMouse();
                    return true;
                }
                if (this._state == MouseStateEnum.DraggingRow)
                {
                    int row = this._htDown.Row;
                    int num6 = this._dragTarget;
                    if ((num6 != row) && (num6 != (row + 1)))
                    {
                        if (num6 > row)
                        {
                            num6--;
                        }
                        DragRowColEventArgs args6 = new DragRowColEventArgs(row, -1, num6);
                        this._view.OnBeforeDragRowCol(args6);
                        if (!args6.Cancel)
                        {
                            this._view.Rows.Move(args6.Row, args6.Position);
                            this._view.OnAfterDragRowCol(args6);
                        }
                    }
                    this._view.Invalidate();
                    this.ResetMouse();
                    return true;
                }
                if (((this._state == MouseStateEnum.PreDraggingCol) && (this._htDrag.Column == this._htDown.Column)) && (this.AllowSortCol(this._htDown.Column) && this.HasScrollableCells()))
                {
                    this._view.MouseSort(this._htDown.Column);
                    this.ResetMouse();
                    return true;
                }
                if (this._state == MouseStateEnum.Selecting)
                {
                    CellRange range = this._view.SelHandler.GetRange();
                    this._view.ShowCell(range.r2, range.c2);
                    this.ResetMouse();
                    return true;
                }
                if ((this._state == MouseStateEnum.PreDraggingCol) || (this._state == MouseStateEnum.PreDraggingRow))
                {
                    this.HandleDownSelection();
                    this.ResetMouse();
                    return true;
                }
                this.ResetMouse();
                return false;
            }
            RowColEventArgs e = new RowColEventArgs(this._htDown.Row, -1);
            int size = this._view.Rows[this._htDown.Row].HeightDisplay + (this._htDrag.Y - this._htDown.Y);
            if (size < 1)
            {
                size = 1;
            }
            switch (this._view.AllowResizing)
            {
                case AllowResizingEnum.RowsUniform:
                case AllowResizingEnum.BothUniform:
                    this._view.Rows.DefaultSize = size;
                    this.ResizeRow(this._htDown.Row, -1);
                    break;

                default:
                    this.ResizeRow(this._htDown.Row, size);
                    break;
            }
            this.ResetMouse();
            this._view.OnAfterResizeRowCol(e);
            return true;
        }

        protected bool HasScrollableCells()
        {
            RowColCollection rows = this._view.Rows;
            if (rows.Count > (rows.Fixed + rows.Frozen))
            {
                return true;
            }
            rows = this._view.Cols;
            return (rows.Count > (rows.Fixed + rows.Frozen));
        }

        internal HitTestInfo HitTest(int x, int y)
        {
            Point point = new Point(x, y);
            point = this._view.GetCellAt(x, y, true);
            int row = point.Y;
            int col = point.X;
            HitTestTypeEnum none = HitTestTypeEnum.None;
            if ((row > -1) && (col > -1))
            {
                none = HitTestTypeEnum.Cell;
                if (row < this._view.Rows.Fixed)
                {
                    none = HitTestTypeEnum.ColumnHeader;
                    int resizeCol = this.GetResizeCol(x, y);
                    if (resizeCol >= 0)
                    {
                        none = HitTestTypeEnum.ColumnResize;
                        col = resizeCol;
                    }
                }
                if ((col < this._view.Cols.Fixed) && (none != HitTestTypeEnum.ColumnResize))
                {
                    if (none == HitTestTypeEnum.Cell)
                    {
                        none = HitTestTypeEnum.RowHeader;
                    }
                    int resizeRow = this.GetResizeRow(x, y);
                    if (resizeRow >= 0)
                    {
                        none = HitTestTypeEnum.RowResize;
                        row = resizeRow;
                    }
                }
                if (this.GetFreezeCol(x, y) > -1)
                {
                    none = HitTestTypeEnum.ColumnFreeze;
                }
                else if (this.GetFreezeRow(x, y) > -1)
                {
                    none = HitTestTypeEnum.RowFreeze;
                }
                switch (none)
                {
                    case HitTestTypeEnum.Cell:
                    case HitTestTypeEnum.ColumnHeader:
                    case HitTestTypeEnum.RowHeader:
                        Rectangle rectangle;
                        switch (this._view.EditHandler.GetEditorType(row, col))
                        {
                            case EditorTypeEnum.DropDown:
                            case EditorTypeEnum.PopUp:
                            case EditorTypeEnum.PopEdit:
                                if ((none == HitTestTypeEnum.Cell) && this._view.CellHasButton(row, col))
                                {
                                    rectangle = this._view.GetCellRect(row, col, false);
                                    if (this._view._editHandler.GetButtonRect(rectangle).Contains(x, y))
                                    {
                                        none = HitTestTypeEnum.EditButton;
                                    }
                                }
                                goto Label_0191;

                            case EditorTypeEnum.Checkbox:
                            {
                                Style styleDisplay = this._view.GetStyleDisplay(row, col);
                                rectangle = this._view.GetCellRect(row, col, false);
                                if (this._view.GetCheckRect(row, col, styleDisplay, rectangle).Contains(x, y))
                                {
                                    none = HitTestTypeEnum.Checkbox;
                                }
                                goto Label_0191;
                            }
                        }
                        goto Label_0191;

                    case HitTestTypeEnum.ColumnResize:
                    case HitTestTypeEnum.ColumnFreeze:
                        goto Label_01B2;
                }
            }
            goto Label_01B2;
        Label_0191:
            if (this.GetOutlineButton(x, y, row, col) > -1)
            {
                none = HitTestTypeEnum.OutlineBar;
            }
            else if (this.GetTreeButton(x, y, row, col))
            {
                none = HitTestTypeEnum.OutlineTree;
            }
        Label_01B2:
            return new HitTestInfo(x, y, row, col, none);
        }

        internal void ResetMouse()
        {
            this._marquee.Reset();
            this._state = MouseStateEnum.None;
            this._scrollTimer.Enabled = false;
            this._listSelection = null;
        }

        internal void ResizeCol(int col, int size)
        {
            CellRange selection = this._view.Selection;
            if (((selection.r1 == this._view.Rows.Fixed) && (selection.r2 == (this._view.Rows.Count - 1))) && selection.ContainsCol(col))
            {
                col = selection.c1;
                while (col <= selection.c2)
                {
                    this._view.Cols[col].Width = size;
                    col++;
                }
            }
            else
            {
                this._view.Cols[col].Width = size;
            }
        }

        internal void ResizeRow(int row, int size)
        {
            CellRange selection = this._view.Selection;
            if (((selection.c1 == this._view.Cols.Fixed) && (selection.c2 == (this._view.Cols.Count - 1))) && selection.ContainsRow(row))
            {
                row = selection.r1;
                while (row <= selection.r2)
                {
                    this._view.Rows[row].Height = size;
                    row++;
                }
            }
            else
            {
                this._view.Rows[row].Height = size;
            }
        }

        protected bool ScrollWhileDragging(int cols, int rows)
        {
            int num;
            Point scrollPosition = this._view.ScrollPosition;
            int num2 = Math.Abs(cols) * 120;
            for (num = 1; num < num2; num += 12)
            {
                int x = scrollPosition.X - (num * cols);
                this._view.ScrollPosition = new Point(x, scrollPosition.Y);
                if (this._view.ScrollPosition.X != x)
                {
                    break;
                }
                this._view.Update();
            }
            num2 = Math.Abs(rows) * 80;
            for (num = 1; num < num2; num += 8)
            {
                int y = scrollPosition.Y - (num * rows);
                this._view.ScrollPosition = new Point(scrollPosition.X, y);
                if (this._view.ScrollPosition.Y != y)
                {
                    break;
                }
                this._view.Update();
            }
            if (this._view.ScrollPosition == scrollPosition)
            {
                return false;
            }
            this._state = (this._view.ScrollPosition.X != scrollPosition.X) ? MouseStateEnum.PreDraggingCol : MouseStateEnum.PreDraggingRow;
            return true;
        }

        internal void TimerTick(object sender, EventArgs e)
        {
            if (((this._state == MouseStateEnum.None) || !this._view.Focused) || !this._view.Capture)
            {
                this._scrollTimer.Enabled = false;
            }
            else
            {
                Point point = this._view.PointToClient(Control.MousePosition);
                if (!this._view.ScrollRectangle.Contains(point.X, point.Y))
                {
                    this.HandleMove(new MouseEventArgs(Control.MouseButtons, 0, point.X, point.Y, 0));
                }
            }
        }

        protected void UpdateDragCol(bool start)
        {
            Rectangle clientRectangle;
            if (start && (this._view.Rows.Fixed > 0))
            {
                this._dragMax = this._dragMin = this._htDown.Column;
                while ((this._dragMin > this._view.Cols.Fixed) && this.AllowDragCol(this._dragMin - 1))
                {
                    this._dragMin--;
                }
                while ((this._dragMax < (this._view.Cols.Count - 1)) && this.AllowDragCol(this._dragMax + 1))
                {
                    this._dragMax++;
                }
                if (this._dragMax == this._dragMin)
                {
                    return;
                }
                this._state = MouseStateEnum.DraggingCol;
                clientRectangle = this._view.GetCellRectDisplay(0, this._htDown.Column, true);
                clientRectangle.Height = this._view.Rows[this._view.Rows.Fixed - 1].Bottom;
                clientRectangle.Intersect(this._view.ClientRectangle);
                ControlPaint.FillReversibleRectangle(this._view.RectangleToScreen(clientRectangle), SystemColors.ControlLightLight);
            }
            this._dragTarget = this.GetTargetCol(true);
            clientRectangle = this._view.ClientRectangle;
            clientRectangle.Width = 3;
            if (this._dragTarget > 0)
            {
                Rectangle rectangle2 = this._view.GetCellRectDisplay(0, this._dragTarget - 1, true);
                clientRectangle.X = rectangle2.Right - 1;
            }
            this._marquee.Update(clientRectangle);
        }

        protected void UpdateDragRow(bool start)
        {
            Rectangle clientRectangle;
            if (start)
            {
                this._state = MouseStateEnum.DraggingRow;
                this._dragMax = this._dragMin = this._htDown.Row;
                while ((this._dragMin > this._view.Rows.Fixed) && this.AllowDragRow(this._dragMin - 1))
                {
                    this._dragMin--;
                }
                while ((this._dragMax < (this._view.Rows.Count - 1)) && this.AllowDragRow(this._dragMax + 1))
                {
                    this._dragMax++;
                }
                if (this._dragMax == this._dragMin)
                {
                    return;
                }
                Rectangle a = this._view.GetCellRectDisplay(this._dragMin, 0, true);
                Rectangle b = this._view.GetCellRectDisplay(this._dragMax, this._view.Cols.Fixed - 1, true);
                clientRectangle = Rectangle.Union(a, b);
                clientRectangle = this._view.GetCellRectDisplay(this._htDown.Row, 0, true);
                clientRectangle.Width = this._view.Cols[this._view.Cols.Fixed - 1].Right;
                clientRectangle.Intersect(this._view.ClientRectangle);
                ControlPaint.FillReversibleRectangle(this._view.RectangleToScreen(clientRectangle), SystemColors.Window);
            }
            this._dragTarget = this.GetTargetRow(true);
            clientRectangle = this._view.ClientRectangle;
            clientRectangle.Height = 3;
            if (this._dragTarget > 0)
            {
                Rectangle rectangle4 = this._view.GetCellRectDisplay(this._dragTarget - 1, 0, true);
                clientRectangle.Y = rectangle4.Bottom - 1;
            }
            this._marquee.Update(clientRectangle);
        }

        protected void UpdateFreezeCol(bool start)
        {
            if (start)
            {
                this._dragMin = this._view.Cols.Fixed;
                this._dragMax = this._view.Cols.Count - 1;
                this._view.LeftCol = 0;
            }
            this._dragTarget = this.GetTargetCol(false);
            Rectangle clientRectangle = this._view.ClientRectangle;
            clientRectangle.Width = 3;
            if (this._dragTarget > 0)
            {
                Rectangle rectangle2 = this._view.GetCellRectDisplay(0, this._dragTarget - 1, true);
                clientRectangle.X = rectangle2.Right - 1;
            }
            this._marquee.Update(clientRectangle);
        }

        protected void UpdateFreezeRow(bool start)
        {
            if (start)
            {
                this._dragMin = this._view.Rows.Fixed;
                this._dragMax = this._view.Rows.Count - 1;
                this._view.TopRow = 0;
            }
            this._dragTarget = this.GetTargetRow(false);
            Rectangle clientRectangle = this._view.ClientRectangle;
            clientRectangle.Height = 3;
            if (this._dragTarget > 0)
            {
                Rectangle rectangle2 = this._view.GetCellRectDisplay(this._dragTarget - 1, 0, true);
                clientRectangle.Y = rectangle2.Bottom - 1;
            }
            this._marquee.Update(clientRectangle);
        }

        protected void UpdateResizeCol(bool start)
        {
            Rectangle clientRectangle;
            if (start)
            {
                clientRectangle = this._view.GetCellRectDisplay(0, this._htDown.Column, true);
                clientRectangle.Y = 0;
                clientRectangle.Width += this._view.ClientRectangle.Right - clientRectangle.Right;
                clientRectangle.Height = this._view.Rows[this._view.Rows.Fixed - 1].Bottom;
            }
            clientRectangle = this._view.ClientRectangle;
            clientRectangle.X = this._htDrag.X - 1;
            clientRectangle.Width = 3;
            this._marquee.Update(clientRectangle);
        }

        protected void UpdateResizeRow(bool start)
        {
            Rectangle clientRectangle;
            if (start && (this._view.Rows.Fixed > 0))
            {
                clientRectangle = this._view.GetCellRectDisplay(this._htDown.Row, 0, true);
                clientRectangle.X = 0;
                clientRectangle.Height += this._view.ClientRectangle.Bottom - clientRectangle.Bottom;
                clientRectangle.Width = this._view.Cols[this._view.Rows.Fixed - 1].Right;
            }
            clientRectangle = this._view.ClientRectangle;
            clientRectangle.Y = this._htDrag.Y - 1;
            clientRectangle.Height = 3;
            this._marquee.Update(clientRectangle);
        }

        internal enum MouseStateEnum
        {
            None,
            PreOLEDrag,
            PreResizingRow,
            PreResizingCol,
            ResizingRow,
            ResizingCol,
            PreFreezingRow,
            PreFreezingCol,
            FreezingRow,
            FreezingCol,
            PreDraggingRow,
            PreDraggingCol,
            DraggingRow,
            DraggingCol,
            Selecting,
            SelectingRows,
            SelectingCols,
            SelectingList
        }
    }
}

